package com.zycfc.zsf.boot.web;

import javax.servlet.*;
import org.springframework.web.servlet.*;
import com.zycfc.zsf.boot.mybatis.page.*;
import com.zycfc.zsf.boot.data.page.*;
import com.zycfc.zsf.boot.web.util.*;
import java.util.*;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.*;
import com.zycfc.zsf.boot.util.text.*;
import com.zycfc.zsf.boot.core.web.data.*;
import com.zycfc.zsf.boot.util.json.*;
import org.slf4j.*;

public abstract class AbstractController extends BaseController
{
    private static final Logger log;
    private static ThreadLocal<ServletRequest> requestThreadLocal;
    private static ThreadLocal<ServletResponse> responseThreadLocal;
    
    public ModelAndView getAutoView() {
        return this.setAutoView(null);
    }
    
    public ModelAndView getAutoView(final ZsfPage<?> pageInfo) {
        return this.setAutoView((BasePage<?>)pageInfo);
    }
    
    public ModelAndView getAutoView(final EsPage<?> pageInfo) {
        return this.setAutoView((BasePage<?>)pageInfo);
    }
    
    private ModelAndView setAutoView(final BasePage<?> pageInfo) {
        String requestURI = RequestHelper.getLocalRequest().getRequestURI();
        AbstractController.log.debug("requestURI:" + requestURI);
        final String contextPath = RequestHelper.getLocalRequest().getContextPath();
        requestURI = requestURI.split("\\.")[0];
        final int cxtIndex = requestURI.indexOf(contextPath);
        if (cxtIndex != -1) {
            requestURI = requestURI.substring(cxtIndex + contextPath.length());
        }
        final String[] paths = requestURI.split("[/]");
        if (paths == null || paths.length > 6 || paths.length < 2) {
            AbstractController.log.error("your request url is not the right pattern, it is not allowed use this getAutoView method");
            throw new IllegalAccessError("url:[" + requestURI + "] is not in this pattern:[/\u5b50\u7cfb\u7edf/\u5305\u540d/\u8868\u5bf9\u5e94\u5b9e\u4f53\u540d/\u5b9e\u4f53\u64cd\u4f5c\u65b9\u6cd5\u540d.xx]");
        }
        final StringBuilder jspPath = new StringBuilder(paths[1]);
        for (int i = 2; i < paths.length - 1; ++i) {
            jspPath.append("/").append(paths[i]);
        }
        jspPath.append("/").append(paths[paths.length - 2]);
        jspPath.append(this.makeFirstLetterUpperCase(paths[paths.length - 1]));
        final ModelAndView model = new ModelAndView(jspPath.toString());
        final Map<String, Object> params = RequestHelper.getQueryMap();
        model.addAllObjects((Map)params);
        if (pageInfo != null) {
            model.addObject("pageInfo", (Object)pageInfo);
        }
        return model;
    }
    
    private String makeFirstLetterUpperCase(final String newStr) {
        if (newStr.length() == 0) {
            return newStr;
        }
        final char[] oneChar = { newStr.charAt(0) };
        final String firstChar = new String(oneChar);
        return firstChar.toUpperCase() + newStr.substring(1);
    }
    
    @ModelAttribute
    public void initHttpServlet(final HttpServletRequest request, final HttpServletResponse response) {
        AbstractController.log.debug("ThreadLocal set success");
        AbstractController.requestThreadLocal.set((ServletRequest)request);
        AbstractController.responseThreadLocal.set((ServletResponse)response);
    }
    
    @ModelAttribute
    public void setRequest(final HttpServletRequest request) {
        RequestHelper.setLocalRequest(request);
    }
    
    public HttpServletRequest request() {
        return (HttpServletRequest)AbstractController.requestThreadLocal.get();
    }
    
    public HttpServletResponse response() {
        return (HttpServletResponse)AbstractController.responseThreadLocal.get();
    }
    
    public HttpSession session() {
        return this.request().getSession();
    }
    
    public ModelAndView buildLoginModelAndView(final String viewName) {
        return this.buildModelAndView(viewName, null);
    }
    
    public ModelAndView buildModelAndView(final String viewName) {
        return this.buildModelAndView(viewName, null);
    }
    
    public ModelAndView buildModelAndView(final String viewName, final Map<String, ?> result) {
        final ModelAndView modelAndView = new ModelAndView(viewName);
        if (null != result && !result.isEmpty()) {
            modelAndView.addAllObjects((Map)result);
        }
        return modelAndView;
    }
    
    public ModelAndView buildAutoModelAndview() {
        return this.buildAutoModelAndview(null);
    }
    
    public ModelAndView buildAutoModelAndview(final Map<String, ?> result) {
        final ModelAndView modelAndView = new ModelAndView(this.request().getRequestURI());
        if (null != result && !result.isEmpty()) {
            modelAndView.addAllObjects((Map)result);
        }
        return modelAndView;
    }
    
    public <T> T getAttribute(final String name) {
        return (T)this.request().getAttribute(name);
    }
    
    public String getParameter(final String name) {
        return this.request().getParameter(name);
    }
    
    public Boolean getParameterToBoolean(final String name) {
        return this.toBoolean(this.request().getParameter(name), null);
    }
    
    public Boolean getParameterToBoolean(final String name, final Boolean defaultvalue) {
        return this.toBoolean(this.request().getParameter(name), defaultvalue);
    }
    
    public Integer getParameterToInt(final String name) {
        return this.toInt(this.request().getParameter(name), null);
    }
    
    public Long getParameterToLong(final String name) {
        return this.toLong(this.request().getParameter(name), null);
    }
    
    public Long getParameterToLong(final String name, final Long defaultValue) {
        return this.toLong(this.request().getParameter(name), defaultValue);
    }
    
    public Double getParameterToDouble(final String name) {
        return this.toDouble(this.request().getParameter(name), null);
    }
    
    public Double getParameterToDouble(final String name, final Double defaultvalue) {
        return this.toDouble(this.request().getParameter(name), defaultvalue);
    }
    
    public Integer getParameterToInt(final String name, final Integer defaultValue) {
        return this.toInt(this.request().getParameter(name), defaultValue);
    }
    
    private Boolean toBoolean(final String value, final Boolean defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return defaultValue;
        }
        if ("0".equals(value) || Boolean.FALSE.toString().equals(value.trim().toLowerCase())) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
    
    private Integer toInt(final String value, final Integer defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return defaultValue;
        }
        if (value.startsWith("N") || value.startsWith("n")) {
            return -Integer.parseInt(value.substring(1));
        }
        return Integer.parseInt(value);
    }
    
    private Long toLong(final String value, final Long defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return defaultValue;
        }
        if (value.startsWith("N") || value.startsWith("n")) {
            return -Long.parseLong(value.substring(1));
        }
        return Long.parseLong(value);
    }
    
    private Double toDouble(final String value, final Double defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return defaultValue;
        }
        return Double.parseDouble(value);
    }
    
    protected String toJson(final DataResponse<?> response) {
        return JsonUtils.objectToJson((Object)response);
    }
    
    static {
        log = LoggerFactory.getLogger((Class)AbstractController.class);
        AbstractController.requestThreadLocal = new ThreadLocal<ServletRequest>();
        AbstractController.responseThreadLocal = new ThreadLocal<ServletResponse>();
    }
}
